// Copyright 2006-2012 Brendan Burns
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef _NMC_H__
#define _NMC_H__

#include <stdlib.h>
#include "nmc_low_level.h"



#ifdef __cplusplus
extern "C" {
#endif  

  /**
   * Init the nmc controller.
   * \param baud The speed to talk over serial
   * \param device The path to the serial device
   * \param Out parameter containing the initialized port.
   * \return The number of modules found on the network.
   **/
  int nmc_init(int baud, const char *device, nmc_port **port);

  /**
   * Set the full PID control.
   * \param port The port to talk to.
   * \param ix The module in the network.
   * See the manual for details on the remaining params.
   **/
  void nmc_set_full_pid_parameters(nmc_port *port, 
				   uint ix, int Kp, int Ki, int Kd, 
				   int integration_limit, int output_limit, 
				   int current_limit,
				   int error_limit, int rate_divisor, 
				   int deadband_compensation);
  /**
   * Simple set PID control parameters.
   * \param port The port to talk to.
   * \param ix The module in the network.
   * \param Kp The proportional constant
   * \param Ki The integral constant
   * \param Kd The derivative constant
   **/
  void nmc_set_pid_parameters(nmc_port *port, 
			      uint ix, uint Kp, uint Ki, uint Kd);
  
  /**
   * Turn on the motors
   * \param port The port to talk to.
   * \param ix The module in the network.
   **/
  void nmc_motors_on(nmc_port *port, int ix);
  
  /**
   * Set the position in encoder ticks.
   * \param port The port to talk to.
   * \param ix The module in the network.
   * \param value The position to achieve in encoder ticks.
   * \param speed The maximum speed to get there (in ticks / s).
   **/
  void nmc_set_position(nmc_port *port, int ix, int value, long speed);

  /**
   * Wait until the module is in position.
   * \param port The port to talk to.
   * \param ix The module in the network.
   **/
  void nmc_wait_position(nmc_port *port, int ix);

  /**
   * Get the current position (in encoder ticks)
   * \param port The port to talk to.
   * \param ix The module in the network.
   * \param request Whether or not to send a new request (slower), or used
   *   a cached value (faster, but potentially out of date)
   **/
  long nmc_get_position(nmc_port *port, int ix, bool request);
  
  void nmc_shutdown(nmc_port *port, char group);

  void nmc_set_path(nmc_port *port, int ix, int *path, int length);
  
  void nmc_set_group(nmc_port *port, int ix, int group, bool leader);
  
  void nmc_start_path(nmc_port *port, int group, int leader);
  
  void nmc_send_pwm(nmc_port *port, int ix, int pwm, bool wait);
  
  void nmc_wait(nmc_port *port, int ix);
  
  int nmc_move_done(nmc_port *port, int addr);

  int nmc_no_op(nmc_port *port, char addr);

#ifdef __cplusplus
}
#endif
#endif

